package labox.innovation.gameserver.skills;

import java.io.File;
import java.util.Map;
import java.util.List;

import labox.innovation.config.Config;
import labox.innovation.gameserver.templates.StatsSet;

import javolution.util.FastList;
import javolution.util.FastMap;

import javax.xml.parsers.DocumentBuilderFactory;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Element;

import java.util.Set;

/**
 * ���� ���ܵ�ѧϰ���� ����
 * ���е���ħλ���� �� ְҵ����
 * version1.0 2010 1.6
 *
 */

public class DoucmentParseLearnSkill
{
    static Logger _log = LoggerFactory.getLogger(DoucmentParseLearnSkill.class.getName());

    private File _file;
    
    //����ѧϰ���ܵ��� �� ѧϰ����
    protected Map<Integer, List<StatsSet>  > _skillLearnStats;
    
    
    public DoucmentParseLearnSkill( File pFile )
    {
    	_file = pFile;
    	_skillLearnStats = new FastMap<Integer, List<StatsSet>  >();
    }
    
    public Boolean parse()
    {
        Document doc;
        try
        {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            factory.setValidating(false);
            factory.setIgnoringComments(true);
            doc = factory.newDocumentBuilder().parse(_file);
        }
        catch (Exception e)
        {
//            _log.error( "Error loading file {} {}" , _file, e);
            _log.error("Error loading file  " + _file , Config.SERVER_ID, e);
            return false;
        }
        try
        {
            parseDocument(doc);
        }
        catch (Exception e)
        { 
//            _log.error( "Error in file {} {}" , _file, e);
            _log.error("Error parse file  " + _file , Config.SERVER_ID, e);
            e.printStackTrace();
            return false;
        }
        
        return true;
    }
   
    
    /**
     * ���� ��ħλ �� ְҵ ���м��ܵ�ѧϰ��������
     * @param iClassId ���� �� ְҵid
     * @return
     */
    public List<StatsSet> getClassSkill( int iClassId )
    {
    	return _skillLearnStats.get( iClassId );
    }
    
    /**
     * �������м���ѧϰ����
     * @return
     */
    public Map<Integer, List<StatsSet>  > getAllSkill()
    {
    	return _skillLearnStats;
    }
    
    /**
     * ���� ����ѧϰ�����ļ�
     * @param doc
     */
    protected void parseDocument( Document doc )
    {
    	Node n=doc.getFirstChild();
    	
    	if( "list".equalsIgnoreCase( n.getNodeName() ) )
    	{
    		n=n.getFirstChild();
    		
            while (n != null && n.getNodeType() != Node.ELEMENT_NODE)
                n = n.getNextSibling();
            
            if( n== null )
            {
            	return;
            }
        	
    		NodeList classList = doc.getElementsByTagName("class");
    		if( classList.getLength() > 0 )
    		{
        		for( int i=0; i < classList.getLength(); i++ )
        		{
        			parseSkillClass( classList.item( i ) );
        		}
        		
    		}
    		else
    		{
    			classList = doc.getElementsByTagName("practice");
         		for( int i=0; i < classList.getLength(); i++ )
        		{
         			parsePracticeSkill( classList.item( i ) );
        		}
         		
    		}

    		
    	}
    	    	
    }// end parseDocument( Document doc )
    
    
    /**
     *  ����ÿ����ħλ����
     * @param node
     */
    protected void parsePracticeSkill( Node node )
    {
    	if( node == null )
    	{
    		return ;
    	}
    	
    	NamedNodeMap attrs = node.getAttributes();
    	
    	int practiceId = Integer.parseInt( attrs.getNamedItem("id").getNodeValue() );
//    	int practiceLvl = Integer.parseInt( attrs.getNamedItem("lvl").getNodeValue() );
    	//���� ��ħλ���ܵ�ѧϰ��������
    	List<StatsSet> tempSet = new FastList<StatsSet>();
    	
    	//�������еļ���
    	NodeList skillList = ( (Element)node ).getElementsByTagName("skill");
    	
    	for( int i=0; i< skillList.getLength(); i++ )
    	{
    		Node n = skillList.item( i );
    		//���漼�ܵ�����ѧϰ����
    		StatsSet set = new StatsSet();
    		set.set("practiceId", practiceId);
    		attrs = n.getAttributes();
    		//������ħλ����
//    		set.set("practicelvl", practiceLvl);
    		int iSkillId = Integer.parseInt( attrs.getNamedItem("skill_id").getNodeValue() );
    		set.set("id", iSkillId);
    		int iSkillLvl = Integer.parseInt( attrs.getNamedItem("skill_lv").getNodeValue() );
    		set.set("lvl", iSkillLvl);
    		
    		NodeList setList = ( (Element )n ).getElementsByTagName("set");
    		for( int j=0; j< setList.getLength(); j++ )
    		{
    			parseBeanSet( setList.item( j ), set ); 
    		}
    		
    		tempSet.add( set );
    	}
    	
    	_skillLearnStats.put( practiceId, tempSet );
    	
    }
    
    
    /**
     * ���� ÿ��ְҵ�ļ���ѧϰ����
     * @param node
     */
    protected void parseSkillClass( Node node )
    {
    	if( node == null )
    	{
    		return;
    	}
    	
    	NamedNodeMap attrs = node.getAttributes();
    	
    	//���������� ְҵ �� ����
    	int iClassid = Integer.parseInt( attrs.getNamedItem("id").getNodeValue() );
    	
    	//������Ҫ��ID
//    	int iParentId = Integer.parseInt( attrs.getNamedItem("parentId").getNodeValue() );
//    	_classParentId.put( iClassid, iParentId );
    	
    	//����� ְҵ �� ���� ���м��ܵ�ѧϰ����
    	//
    	List<StatsSet> tempSet = new FastList<StatsSet>();
    	
    	//�������еļ���
    	NodeList skillList = ( (Element)node ).getElementsByTagName("skill");
    	for( int i=0; i< skillList.getLength(); i++ )
    	{
    		Node n = skillList.item( i );
    		//���漼�ܵ�����ѧϰ����
    		StatsSet set = new StatsSet();
    		attrs = n.getAttributes();
    		//����  ְҵ���� �� ��ħλ����
    		//TODO:
    		int iSkillId = Integer.parseInt( attrs.getNamedItem("skill_id").getNodeValue() );
    		set.set("id", iSkillId);
    		int iSkillLvl = Integer.parseInt( attrs.getNamedItem("skill_lv").getNodeValue() );
    		set.set("lvl", iSkillLvl);
    		
    		NodeList setList = ( (Element )n ).getElementsByTagName("set");
    		for( int j=0; j< setList.getLength(); j++ )
    		{
    			parseBeanSet( setList.item( j ), set ); 
    		}
    		
    		tempSet.add( set );
    	}
    	
//    	//�������еļ���
//    	//old
//    	for( Node n = node.getFirstChild(); n != null; n = n.getNextSibling() )
//    	{
//            while (n != null && n.getNodeType() != Node.ELEMENT_NODE)
//                n = n.getNextSibling();
//            
//            if( n == null )
//            {
//            	break;
//            }
//    		//���漼�ܵ�����ѧϰ����
//    		StatsSet set = new StatsSet();
//    		attrs = n.getAttributes();
//    		int iSkillId = Integer.parseInt( attrs.getNamedItem("id").getNodeValue() );
//    		set.set("id", iSkillId);
//    		int iSkillLvl = Integer.parseInt( attrs.getNamedItem("lvl").getNodeValue() );
//    		set.set("lvl", iSkillLvl);
//    		
//    		
//    		for( Node cn = n.getFirstChild(); cn != null; cn = cn.getNextSibling() )
//    		{
//                while (cn != null && cn.getNodeType() != Node.ELEMENT_NODE)
//                    cn = cn.getNextSibling();
//                
//                if( cn == null  )
//                {
//                	break;
//                }
//    			//���������� ��ǰ���ܵ� ��������
//    			parseBeanSet( cn, set );    			
//    		}// end for( Node cn = n.getFirstChild(); cn != null; cn = cn.getNextSibling() )
//    		
//    		tempSet.add( set );
//    		
//    	}// end for( Node n = node.getFirstChild(); n != null; n = n.getNextSibling() )
    	
    	_skillLearnStats.put( iClassid, tempSet );
    	
    }// end 
    
    /**
     * ���� node �����ԣ� ���������ֶμ��뵽 set��ȥ
     * @param node
     * @param set
     */
    protected void parseBeanSet( Node node , StatsSet set )
    {
    	if( node == null )
    	{
    		return;
    	}
        String name = node.getAttributes().getNamedItem("name").getNodeValue().trim();
        String value = node.getAttributes().getNamedItem("val").getNodeValue().trim();
        
        set.set(name, value);
    }
    
    public static void main(String args[])
    {
    	File file = new File("test.xml");
    	DoucmentParseLearnSkill ds = new DoucmentParseLearnSkill( file );
    	
    	ds.parse();
    	
    	Map<Integer, List<StatsSet>  > allSets = ds.getAllSkill();
    	Set<Integer> keyset = allSets.keySet();
    	Integer[] keys = new Integer[ allSets.size() ];
    	keyset.toArray( keys );
    	for( int i=0; i<keyset.size(); i++ )
    	{
//    		System.out.println( keys[i] );
//    		System.out.println( ":---");
    		List<StatsSet> sss= allSets.get( keys[i] );
    		for( int j=0; j<sss.size(); j++ )
    		{
    			StatsSet ss = sss.get( j );
    			
//    			System.out.print( ss.getInteger("id") );
//    			System.out.print( "***");
//    			System.out.print( ss.getInteger("lvl") );
    		}
    	}
    }
    
}
